package com.glsc.ngateway.platform.service.itflow.flowstrategy.cmdb.deviceIn.taskPostHandler;

import com.alibaba.excel.util.CollectionUtils;
import com.glsc.ngateway.common.api.common.enums.Constant;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbDeviceDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormDeviceIn;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.converter.FlowFormDeviceInConverter;
import com.glsc.ngateway.common.api.flowable.dto.CurrentTaskInfoDto;
import com.glsc.ngateway.common.api.platform.dto.user.UserLeadersDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowStatus;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.*;
import com.glsc.ngateway.platform.service.MailService;
import com.glsc.ngateway.platform.service.UserService;
import com.glsc.ngateway.platform.service.cmdb.*;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractHandlerHelper;
import com.netflix.discovery.shared.Pair;
import io.jsonwebtoken.lang.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.glsc.ngateway.common.api.common.enums.DictConstant.CMDB_CONFIRM;

/**
 * @author zhengyr
 * @date 2023/8/4-13:49
 */
@Component
public class DIStepHandlerHelper extends AbstractHandlerHelper {
    
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final String ADDTYPE = "0";
    private final String DELETETYPE = "1";
    @Autowired
    FlowFormDeviceInRepo flowFormDeviceInRepo;
    @Autowired
    FlowFormCPUInDetailRepo cpuInDetailRepo;
    @Autowired
    FlowFormMemoryInDetailRepo memoryInDetailRepo;
    @Autowired
    FlowFormDiskInDetailRepo diskInDetailRepo;
    @Autowired
    FlowFormDeviceInDetailRepo deviceInDetailRepo;

    @Autowired
    private UserService userService;
    @Autowired
    private MailService mailService;

    @Autowired
    CmdbDeviceDetailService cmdbDeviceDetailService;
    @Autowired
    CmdbDeviceStandardService cmdbDeviceStandardService;
    @Autowired
    CmdbCpuDetailService cmdbCpuDetailService;
    @Autowired
    CmdbMemoryDetailService cmdbMemoryDetailService;
    @Autowired
    CmdbDiskDetailService cmdbDiskDetailService;
    @Autowired
    CmdbPartDetailService cmdbPartDetailService;

    protected void endTaskAfterHandle(String processId, String operator){
        FlowFormDeviceIn formMainDo = flowFormDeviceInRepo.findByProcessId(processId);
        //抄送给上级领导
        PlatformUserDto createUser = userService.findByUsername(operator);
        //直属领导
        UserLeadersDto userLeadersDto = userService.getDirectLeaderAndPrimaryDepartmentLeader(createUser);
        if (CollectionUtils.isEmpty(userLeadersDto.getDirectLeaders())) {
            logger.info(String.format("CMDB设备入库流程%c未找到直属领导信息。发起人：%s",formMainDo.getProcessId(), operator));
        }else{
            this.copyPorcess(formMainDo.getProcessId(), operator,
                    userLeadersDto.getDirectLeaders()
                    , String.format("【抄送】-【CMDB设备入库流程】-【%s】已结束", formMainDo.getProcessTitle())
                    , AbstractHandlerHelper.GATEWAY_CMDB_FLOW_URL + "deviceInFlowAudit?flowProcessId=" + formMainDo.getProcessId()
                    , String.format("申请人：" + formMainDo.getFlowCreateOperatorName() +
                            "<br/>  请知悉。可至国联技术服务平台内查阅相关事宜。"));
        }
    }

    @Transactional
    protected void updatePartData(String processId, String operator){
        FlowFormDeviceIn formMainDo = flowFormDeviceInRepo.findByProcessId(processId);
        //更新业务表数据
        if(formMainDo.getIsClose()!=0) {
            return;
        }
        List<CmdbDeviceDetail> deviceInDetailList = FlowFormDeviceInConverter.dto2Do(deviceInDetailRepo.findAllByprocessId(processId));
        if(!CollectionUtils.isEmpty(deviceInDetailList)){
            deviceInDetailList.stream().forEach(h->{
                //同时配件明细入库
                h.setLifeStatus(DictConstant.LIFE_CYCLE_IN);
                cmdbDeviceDetailService.addOrUpdate(h,operator,CMDB_CONFIRM);
                cmdbDeviceDetailService.deviceDetailWithPartIn(h , operator,CMDB_CONFIRM);
            });
        }
        //更新流程主表isClose
        formMainDo.setIsClose(1);
        formMainDo.setStatus(ITFlowStatus.END.getCode());
        flowFormDeviceInRepo.save(formMainDo);
    }

    /**
     * 发送邮件通知
     */
    public void notify(@NotNull ResponseSituationDto processInfo, String processTitle, String creator) {
        if (Collections.isEmpty(processInfo.getCurrentTaskInfoDtoList())) {
            logger.info("设备入库流程-通知失败：当前无人员可通知");
        } else {
            String title = "【国联技术服务平台提醒】您有新的待办";
            String headTitle = String.format("【待办】-【CMDB设备入库流程】-【%s】", processTitle);
            String mailContent = String.format("申请人：" + creator +
                    "<br/>  申请设备入库" +
                    "<br/>  请操作。" +
                    "可至国联技术服务平台内查阅相关事宜。"
            );
            List<Pair<CurrentTaskInfoDto, List<User>>> mailList = processInfo.getCurrentTaskInfoDtoList().stream()
                    .map(t -> new Pair<>(t, userService.findAllByAccountList(t.getCurrentAssigneeList())))
                    .filter(t -> !CollectionUtils.isEmpty(t.second()))
                    .collect(Collectors.toList());
            if (Collections.isEmpty(mailList)) {
                logger.info("CMDB设备入库流程-通知失败：未找到邮箱");
            } else {
                mailList.forEach(p -> {
                    List<String> currentTaskIdList = p.first().getCurrentTaskIdList();
                    Map<String, String> emailMap = p.second().stream().collect(Collectors.toMap(User::getName, User::getEmail));
                    for (int i = 0; i < currentTaskIdList.size(); i++) {
                        String titleLink = AbstractHandlerHelper.GATEWAY_CMDB_FLOW_URL + "deviceInFlowAudit?flowTaskId=" + currentTaskIdList.get(i);
                        mailService.sendMail(new String[]{emailMap.get(p.second().get(i).getName())}, null, title, titleLink, headTitle, mailContent, null, Constant.MAIL_TYPE_IT_FLOW);
                    }
                });
            }
        }
    }
}
